from sqlalchemy import Column, Integer, String, Text, Boolean, DateTime, Table, JSON, Enum, ForeignKey
from sqlalchemy.orm import relationship, foreign
from datetime import datetime
from app.database import Base
import enum


# 多对多关系表（移除外键约束）
agent_tools = Table(
    'agent_tools',
    Base.metadata,
    Column('agent_id', Integer, primary_key=True),
    Column('tool_id', Integer, primary_key=True),
    Column('sort', Integer, default=0)
)


class UserStatus(str, enum.Enum):
    ACTIVE = "ACTIVE"
    DISABLED = "DISABLED"


class ModelKind(str, enum.Enum):
    DIALOG = "DIALOG"
    EMBEDDING = "EMBEDDING"


class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True, index=True)
    phone = Column(String(20), unique=True, index=True, nullable=False)
    password_hash = Column(String(255), nullable=False)
    nickname = Column(String(50))
    avatar_url = Column(String(500))
    status = Column(String(20), default="active")
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（移除级联删除，使用 primaryjoin + foreign）
    sessions = relationship("Session", back_populates="user", primaryjoin="User.id==foreign(Session.user_id)")


class Model(Base):
    __tablename__ = "models"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    provider = Column(String(50), nullable=False)  # qwen, openai, claude, etc.
    kind = Column(String(20), nullable=False)  # dialog, embedding
    description = Column(Text)
    enabled = Column(Boolean, default=True)
    api_key = Column(String(500))  # 加密存储
    params = Column(JSON)  # 温度、max_tokens 等参数
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（使用 primaryjoin + foreign）
    agents = relationship("Agent", back_populates="model", primaryjoin="Model.id==foreign(Agent.model_id)")


class Tool(Base):
    __tablename__ = "tools"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    type = Column(String(50), nullable=False)  # http, function, etc.
    category = Column(String(50))
    description = Column(Text)
    tags = Column(JSON)  # ["tag1", "tag2"]
    schema = Column(JSON)  # 工具的参数 schema
    auth = Column(JSON)  # 鉴权信息
    enabled = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（多对多，使用 primaryjoin + secondaryjoin）
    agents = relationship(
        "Agent", 
        secondary=agent_tools, 
        back_populates="tools",
        primaryjoin="Tool.id==agent_tools.c.tool_id",
        secondaryjoin="Agent.id==agent_tools.c.agent_id"
    )


class KnowledgeBase(Base):
    __tablename__ = "knowledge_bases"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    description = Column(Text)
    embedding_model = Column(String(100))
    vector_store = Column(String(50))  # pgvector, milvus, faiss
    config = Column(JSON)  # 切分策略、TopK、阈值等
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（移除级联删除，使用 primaryjoin + foreign）
    documents = relationship("Document", back_populates="knowledge_base", primaryjoin="KnowledgeBase.id==foreign(Document.kb_id)")
    agents = relationship("Agent", back_populates="knowledge_base", primaryjoin="KnowledgeBase.id==foreign(Agent.rag_kb_id)")


class Document(Base):
    __tablename__ = "documents"
    
    id = Column(Integer, primary_key=True, index=True)
    kb_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    title = Column(String(200), nullable=False)
    file_path = Column(String(500))  # 文件存储路径
    file_type = Column(String(50))  # pdf, docx, txt, md 等
    file_size = Column(Integer)  # 文件大小（字节）
    source_url = Column(String(500))
    status = Column(String(20), default="pending")  # pending, processing, completed, failed
    error_msg = Column(Text)  # 处理失败时的错误信息
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（移除级联删除，使用 primaryjoin + foreign）
    knowledge_base = relationship("KnowledgeBase", back_populates="documents", primaryjoin="foreign(Document.kb_id)==KnowledgeBase.id")
    chunks = relationship("DocumentChunk", back_populates="document", primaryjoin="Document.id==foreign(DocumentChunk.doc_id)")


class DocumentChunk(Base):
    __tablename__ = "document_chunks"
    
    id = Column(Integer, primary_key=True, index=True)
    doc_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    kb_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    content = Column(Text, nullable=False)
    embedding = Column(Text)  # 存储为 JSON 字符串
    meta = Column(JSON)  # 页码、章节等元数据
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 关系（使用 primaryjoin + foreign）
    document = relationship("Document", back_populates="chunks", primaryjoin="foreign(DocumentChunk.doc_id)==Document.id")


class Agent(Base):
    __tablename__ = "agents"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    description = Column(Text)
    is_hot = Column(Boolean, default=False)
    model_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    category_id = Column(Integer, index=True)  # 移除外键约束
    params = Column(JSON)  # 温度、TopP、系统提示词等
    role = Column(JSON)  # {name, background, persona}
    rag_kb_id = Column(Integer, index=True)  # 移除外键约束
    enabled = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（移除级联删除，使用 primaryjoin + foreign）
    model = relationship("Model", back_populates="agents", primaryjoin="foreign(Agent.model_id)==Model.id")
    category = relationship("Category", back_populates="agents", primaryjoin="foreign(Agent.category_id)==Category.id")
    tools = relationship(
        "Tool", 
        secondary=agent_tools, 
        back_populates="agents",
        primaryjoin="Agent.id==agent_tools.c.agent_id",
        secondaryjoin="Tool.id==agent_tools.c.tool_id"
    )
    knowledge_base = relationship("KnowledgeBase", back_populates="agents", primaryjoin="foreign(Agent.rag_kb_id)==KnowledgeBase.id")
    sessions = relationship("Session", back_populates="agent", primaryjoin="Agent.id==foreign(Session.agent_id)")


class Category(Base):
    __tablename__ = "categories"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(50), nullable=False)
    sort = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 关系（使用 primaryjoin + foreign）
    agents = relationship("Agent", back_populates="category", primaryjoin="Category.id==foreign(Agent.category_id)")


class AgentCategory(Base):
    __tablename__ = "agent_categories"
    
    agent_id = Column(Integer, primary_key=True)  # 移除外键约束
    category_id = Column(Integer, primary_key=True)  # 移除外键约束


class Session(Base):
    __tablename__ = "sessions"
    
    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    agent_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    title = Column(String(200), default="新会话")
    pinned = Column(Boolean, default=False)
    status = Column(String(20), default="active")
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系（移除级联删除，使用 primaryjoin + foreign）
    user = relationship("User", back_populates="sessions", primaryjoin="foreign(Session.user_id)==User.id")
    agent = relationship("Agent", back_populates="sessions", primaryjoin="foreign(Session.agent_id)==Agent.id")
    messages = relationship("Message", back_populates="session", primaryjoin="Session.id==foreign(Message.session_id)")


class Message(Base):
    __tablename__ = "messages"
    
    id = Column(Integer, primary_key=True, index=True)
    session_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    role = Column(String(20), nullable=False)  # user, assistant, tool, system
    content = Column(Text)
    tool_name = Column(String(100))
    tool_args = Column(JSON)
    token_usage = Column(JSON)  # {prompt, completion, total}
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 关系（使用 primaryjoin + foreign）
    session = relationship("Session", back_populates="messages", primaryjoin="foreign(Message.session_id)==Session.id")


class SMSCode(Base):
    __tablename__ = "sms_codes"
    
    id = Column(Integer, primary_key=True, index=True)
    phone = Column(String(20), nullable=False, index=True)
    code = Column(String(6), nullable=False)  # 存储原始验证码，不加密
    purpose = Column(String(20), nullable=False)  # register, login, reset
    attempts = Column(Integer, default=0)
    expire_at = Column(DateTime, nullable=False)
    throttled_until = Column(DateTime)
    created_at = Column(DateTime, default=datetime.utcnow)


class HotTool(Base):
    __tablename__ = "hot_tools"
    
    id = Column(Integer, primary_key=True, index=True)
    agent_id = Column(Integer, nullable=False, index=True)  # 移除外键约束
    sort = Column(Integer, default=0)
    enabled = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)


class Admin(Base):
    __tablename__ = "admins"
    
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, nullable=False, index=True)
    password_hash = Column(String(255), nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

